<!DOCTYPE html>
<html lang=zh>
<head>
  <meta charset="utf-8">
  
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="renderer" content="webkit">
  <meta http-equiv="Cache-Control" content="no-transform" />
  <meta http-equiv="Cache-Control" content="no-siteapp" />
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="format-detection" content="telephone=no,email=no,adress=no">
  <!-- Color theme for statusbar -->
  <meta name="theme-color" content="#000000" />
  <!-- 强制页面在当前窗口以独立页面显示,防止别人在框架里调用页面 -->
  <meta http-equiv="window-target" content="_top" />
  
  
  <title>面试题 | 雨落</title>
  <meta name="description" content="vueMVVM 和 MVM 什么是 MVVM：视图模型双向数据绑定，分为数据层（model），视图层（view），控制层（ViewModel），控制层是数据层和视图层的桥梁，视图变化会导致数据更新，数据更新也会导致视图变化   MVM：MVM 分为模型（Model）：是用于处理应用程序数据逻辑部分。通常模型对象负责在数据库中存取数据，视图（view）：是应用程序中处理数据显示的本分。通常视图是依据">
<meta property="og:type" content="article">
<meta property="og:title" content="面试题">
<meta property="og:url" content="https://gitee.com/Yu-Luoboke/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/index.html">
<meta property="og:site_name" content="雨落">
<meta property="og:description" content="vueMVVM 和 MVM 什么是 MVVM：视图模型双向数据绑定，分为数据层（model），视图层（view），控制层（ViewModel），控制层是数据层和视图层的桥梁，视图变化会导致数据更新，数据更新也会导致视图变化   MVM：MVM 分为模型（Model）：是用于处理应用程序数据逻辑部分。通常模型对象负责在数据库中存取数据，视图（view）：是应用程序中处理数据显示的本分。通常视图是依据">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2023-11-29T15:29:49.000Z">
<meta property="article:modified_time" content="2023-11-29T15:58:44.654Z">
<meta property="article:author" content="lianghongming">
<meta name="twitter:card" content="summary">
  <!-- Canonical links -->
  <link rel="canonical" href="https://gitee.com/Yu-Luoboke/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/index.html">
  
    <link rel="alternate" href="/atom.xml" title="雨落" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png" type="image/x-icon">
  
  
<link rel="stylesheet" href="/blog/css/style.css">

  
  
  
  
<meta name="generator" content="Hexo 5.2.0"></head>


<body class="main-center" itemscope itemtype="http://schema.org/WebPage">
  <header class="header" itemscope itemtype="http://schema.org/WPHeader">
  <div class="slimContent">
    <div class="navbar-header">
      
      
      <div class="profile-block text-center">
        <a id="avatar" href="http://yu-luoboke.gitee.io/blog" target="_blank">
          <img class="img-circle img-rotate" src="/blog/images/avatar.jpg" width="200" height="200">
        </a>
        <h2 id="name" class="hidden-xs hidden-sm">雨落</h2>
        <h3 id="title" class="hidden-xs hidden-sm hidden-md">前端开发-奋斗青年</h3>
        <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i> GuangZhou, China</small>
      </div>
      
      <div class="search" id="search-form-wrap">

    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="搜索" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i class="icon icon-search"></i></button>
            </span>
        </div>
    </form>
    <div class="ins-search">
  <div class="ins-search-mask"></div>
  <div class="ins-search-container">
    <div class="ins-input-wrapper">
      <input type="text" class="ins-search-input" placeholder="想要查找什么..." x-webkit-speech />
      <button type="button" class="close ins-close ins-selectable" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
    </div>
    <div class="ins-section-wrapper">
      <div class="ins-section-container"></div>
    </div>
  </div>
</div>


</div>
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
    </div>
    <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
      <ul class="nav navbar-nav main-nav menu-highlight">
        
        
        <li class="menu-item menu-item-home">
          <a href="/blog/.">
            
            <i class="icon icon-home-fill"></i>
            
            <span class="menu-title">首页</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives">
            
            <i class="icon icon-archives-fill"></i>
            
            <span class="menu-title">归档</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-categories">
          <a href="/blog/categories">
            
            <i class="icon icon-folder"></i>
            
            <span class="menu-title">分类</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-tags">
          <a href="/blog/tags">
            
            <i class="icon icon-tags"></i>
            
            <span class="menu-title">标签</span>
          </a>
        </li>
        
      </ul>
      
	
    <ul class="social-links">
    	
        <li><a href="http://yu-luoboke.gitee.io/blog" target="_blank" title="Github" ><i class="icon icon-github"></i></a></li>
        
    </ul>

    </nav>
  </div>
</header>

  
    <aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">公告</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">
                <p>欢迎交流与分享经验!</p>
            </div>
        </div>
    </div>
</div>

    
      
  <div class="widget">
    <h3 class="widget-title">分类</h3>
    <div class="widget-body">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Git/">Git</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/HTML-CSS/">HTML + CSS</a><span class="category-list-count">7</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/JVM%EF%BC%88Java%E8%99%9A%E6%8B%9F%E6%9C%BA%EF%BC%89-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E7%AE%97%E6%B3%95/">JVM（Java虚拟机）-垃圾回收算法</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Node/">Node</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Project/">Project</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/React/">React</a><span class="category-list-count">4</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/SVN/">SVN</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Vue-typescript/">Vue-typescript</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/gitee/">gitee</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/iOS/">iOS</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/js/">js</a><span class="category-list-count">12</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/vue/">vue</a><span class="category-list-count">13</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/web-serve%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E6%9C%8D%E5%8A%A1%E5%99%A8/">web serve静态资源服务器</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/webpack/">webpack</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E5%89%8D%E7%AB%AF%E8%87%AA%E5%8A%A8%E5%8C%96/">前端自动化</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/">小程序</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E7%A7%BB%E5%8A%A8%E7%AB%AF/">移动端</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E7%BB%8F%E9%AA%8C/">经验</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a><span class="category-list-count">4</span></li></ul>
    </div>
  </div>


    
      

    
      
    
      
  <div class="widget">
    <h3 class="widget-title">归档</h3>
    <div class="widget-body">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2024/04/">四月 2024</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2023/11/">十一月 2023</a><span class="archive-list-count">8</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2023/09/">九月 2023</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/12/">十二月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/08/">八月 2022</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/07/">七月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/06/">六月 2022</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/04/">四月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/01/">一月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/12/">十二月 2021</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/11/">十一月 2021</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/10/">十月 2021</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/04/">四月 2021</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/03/">三月 2021</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/02/">二月 2021</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/01/">一月 2021</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2020/12/">十二月 2020</a><span class="archive-list-count">15</span></li></ul>
    </div>
  </div>


    
      
  <div class="widget">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget-body">
      <ul class="recent-post-list list-unstyled no-thumbnail">
        
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/HTML-CSS/">HTML + CSS</a>
              </p>
              <p class="item-title">
                <a href="/blog/2024/04/15/%E6%8B%96%E5%8A%A8%E5%92%8C%E7%82%B9%E5%87%BB%E5%BC%B9%E7%AA%97/" class="title">拖动和点击弹窗</a>
              </p>
              <p class="item-date">
                <time datetime="2024-04-15T12:22:06.000Z" itemprop="datePublished">2024-04-15</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/html%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">html面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:58:27.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/css%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">css面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:57:17.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">js面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:37:30.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:29:49.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
      </ul>
    </div>
  </div>
  

    
  </div>
</aside>

  
  
<main class="main" role="main">
  <div class="content">
  <article id="post-面试题" class="article article-type-post" itemscope itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      
        
  
    <h1 class="article-title" itemprop="name">
      面试题
    </h1>
  

      
      <div class="article-meta">
        <span class="article-date">
    <i class="icon icon-calendar-check"></i>
	<a href="/blog/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/" class="article-date">
	  <time datetime="2023-11-29T15:29:49.000Z" itemprop="datePublished">2023-11-29</time>
	</a>
</span>
        
  <span class="article-category">
    <i class="icon icon-folder"></i>
    <a class="article-category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
  </span>

        

        

        <span class="post-comment"><i class="icon icon-comment"></i> <a href="/blog/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/#comments" class="article-comment-link">评论</a></span>
        
      </div>
    </div>
    <div class="article-entry marked-body" itemprop="articleBody">
      
        <h1 id="vue"><a href="#vue" class="headerlink" title="vue"></a>vue</h1><h3 id="MVVM-和-MVM"><a href="#MVVM-和-MVM" class="headerlink" title="MVVM 和 MVM"></a>MVVM 和 MVM</h3><blockquote>
<p><strong>什么是 MVVM：</strong>视图模型双向数据绑定，分为数据层（model），视图层（view），控制层（ViewModel），控制层是数据层和视图层的桥梁，视图变化会导致数据更新，数据更新也会导致视图变化</p>
</blockquote>
<blockquote>
<p><strong>MVM：</strong>MVM 分为模型（Model）：是用于处理应用程序数据逻辑部分。通常模型对象负责在数据库中存取数据，视图（view）：是应用程序中处理数据显示的本分。通常视图是依据模型数据创建的，控制器（Controller）：是应用程序处理用户交互的部分。通常控制器负责从视图读取数据，控制用户输入，并向模型发送数据，</p>
</blockquote>
<h3 id="1、vue-中的-key-的作用以及不建议使用-index-作为-key-值"><a href="#1、vue-中的-key-的作用以及不建议使用-index-作为-key-值" class="headerlink" title="1、vue 中的 key 的作用以及不建议使用 index 作为 key 值"></a>1、vue 中的 key 的作用以及不建议使用 index 作为 key 值</h3><blockquote>
<p><strong>一、 key 的作用：</strong>Vue 中使用虚拟 dom 且根据 diff 算法进行新旧 DOM 对比，对比的唯一依据或者标识就是 key，通过这个 key去标识，就可以判断元素有没有发生变化，可以有效的解决vue的就地复用情况。（什么是就地复用：当 Vue 正在更新使用 v-for 渲染的元素列表时，它默认使用“就地更新”的策略。如果数据项的顺序被改变，Vue 将不会移动 DOM 元素来匹配数据项的顺序，而是就地更新每个元素，并且确保它们在每个索引位置正确渲染。简单点来说就是 key 发生了变化，元素就更新，否则复用该元素）利用 key 的唯一性生成 map 对象来获取对应节点，比遍历的方式更快，从而实现了　DOM　的高效更新。key 的唯一性也会防止错误的渲染</p>
</blockquote>
<blockquote>
<p><strong>二、 不建议使用数组的 index 作为 key 值：</strong>因为使用 index 做 key，破坏顺序操作的时候，key 对应的index 就会发生变化，就会导致本该复用的元素也会重新渲染，从而导致了性能的消耗。也有可能造成其它的问题</p>
</blockquote>
<blockquote>
<p><strong>三、 解决方案：</strong>既然知道用 index 在某些情况下带来很不好的影响，那平时我们在开发当中怎么去解决这种情况呢？其实只要保证 key 唯一不变就行，一般在开发中用的比较多就是下面三种情况：1、在开发中最好每条数据使用唯一标识固定的数据作为 key，比如后台返回的 ID，手机号，身份证号等唯一值。2、可以采用 Symbol 作为 key，Symbol 是 ES6 引入了一种新的原始数据类型 Symbol ，表示独一无二的值，最大的用法是用来定义对象的唯一属性名。</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a=<span class="built_in">Symbol</span>(<span class="string">&#x27;测试&#x27;</span>)</span><br><span class="line"><span class="keyword">let</span> b=<span class="built_in">Symbol</span>(<span class="string">&#x27;测试&#x27;</span>)</span><br><span class="line"><span class="built_in">console</span>.log(a===b)<span class="comment">//false</span></span><br><span class="line"></span><br><span class="line">&lt;div v-<span class="keyword">for</span>=<span class="string">&quot;(item,index) in arr&quot;</span> :key=<span class="string">&quot;Symbol(index)&quot;</span>&gt;&lt;/div&gt;</span><br></pre></td></tr></table></figure>


<h3 id="2、为什么-vue-的-data-是一个函数？"><a href="#2、为什么-vue-的-data-是一个函数？" class="headerlink" title="2、为什么 vue 的 data 是一个函数？"></a>2、为什么 vue 的 data 是一个函数？<div id="a"></div></h3><blockquote>
<p>data之所以是一个函数，是因为一个组件可能会多处调用，而每一次调用就会执行data函数并返回新的数据对象，这样，可以避免多处调用之间的数据污染。data 如果不是一个函数，在组件被多次调用的情况下，实例之间会相互影响，即修改一个实例，另外的实例也会发生改变，造成数据的污染。</p>
</blockquote>
<h3 id="3、vue-组件通讯"><a href="#3、vue-组件通讯" class="headerlink" title="3、vue 组件通讯"></a>3、vue 组件通讯</h3><blockquote>
<p><strong>一、props 和 $emit：</strong>父组件通过 props 向子组件传递数据，子组件通过 $emit 出发父组件的自定义事件，进而向父组件传递数据</p>
</blockquote>
<blockquote>
<p>二、组件中可以使用 <strong>$parent</strong> 和 <strong>$children</strong> 获取到父组件实例和子组件实例，进而获取数据</p>
</blockquote>
<blockquote>
<p><strong>三、$attrs 和 $listeners：</strong>子组件可以通过 $attr 获取父组件在子组件上添加的属性（除了被子组件prop接收的属性）；子组件可以通过 $listeners 获取父组件在子组件上添加的监听事件。如果你不希望组件的根元素继承 attribute，你可以在组件的选项中设置 inheritAttrs: false</p>
</blockquote>
<blockquote>
<p>四、使用$refs获取组件实例，进而获取数据</p>
</blockquote>
<blockquote>
<p>vuex</p>
</blockquote>
<blockquote>
<p>使用 eventBus 的 $on 和 $emit 进行跨组件通讯</p>
</blockquote>
<blockquote>
<p>使用浏览器的缓存</p>
</blockquote>
<h3 id="4、vue-的生命周期"><a href="#4、vue-的生命周期" class="headerlink" title="4、vue 的生命周期"></a>4、vue 的生命周期</h3><blockquote>
<p><strong>1、beforeCreate</strong> 在实例初始化之后执行，在当前阶段 data、methods、computed 以及 watch 上的数据和方法都不能被访问。</p>
</blockquote>
<blockquote>
<p><strong>2、created</strong> 在实例创建完成后调用，这里没有 $el，如果非要想与 DOM 进行交互，可以通过vm.$nextTick 来访问 DOM。可以访问 methods 中的方法和 data 种的数据</p>
</blockquote>
<blockquote>
<p><strong>3、beforeMount</strong>，模板已经在内存种编译完成，但是尚未挂载到页面当中，此时的页面还是旧的页面</p>
</blockquote>
<blockquote>
<p><strong>4、mounted</strong> 在挂载完成后发生，在当前阶段，真实的 Dom 挂载完毕，数据完成双向绑定，可以访问到 Dom节点</p>
</blockquote>
<blockquote>
<p><strong>5、beforeUpdate</strong> 数据更新时调用</p>
</blockquote>
<blockquote>
<p><strong>6、updated</strong> 发生在更新完成之后，当前阶段组件 Dom 已经完成更新</p>
</blockquote>
<blockquote>
<p><strong>7、beforeDestroy</strong> 实例销毁之前调用</p>
</blockquote>
<blockquote>
<p><strong>8、destroy</strong> Vue实例销毁后调用。调用后，Vue实例指示的东西都会解绑定，所有的事件监听器会被移除</p>
</blockquote>
<blockquote>
<p><strong>9、缓存组件 keep-alive 的生命周期：</strong>activated 组件被激活时使用，deactivated，组件被销毁时调用</p>
</blockquote>
<blockquote>
<p><strong>10、异步请求在哪一步发起？</strong>在钩子函数 created、beforeMount、mounted 中进行异步请求，因为在这三个钩子函数中，data已经创建，可以将服务器端返回的数据进行赋值</p>
</blockquote>
<h3 id="父子组件生命周期的执行顺序"><a href="#父子组件生命周期的执行顺序" class="headerlink" title="父子组件生命周期的执行顺序"></a>父子组件生命周期的执行顺序</h3><blockquote>
<p>父beforeCreate -&gt; 父created -&gt; 父beforeMount -&gt; 子beforeCreate -&gt; 子created -&gt; 子beforeMount -&gt; 子mounted -&gt; 父mounted-&gt;父beforeUpdate-&gt;子beforeUpdate-&gt;子updated-&gt;父updated-&gt;父beforeDestroy-&gt;子beforeDestroy-&gt;子destroyed-&gt;父destroyed</p>
</blockquote>
<h3 id="vue-双向绑定的原理"><a href="#vue-双向绑定的原理" class="headerlink" title="vue 双向绑定的原理"></a>vue 双向绑定的原理</h3><blockquote>
<p>采用数据劫持结合发布者-订阅者模式的方式，通过Object.defineProperty()来劫持各个属性的setter、getter，在数据变动时发布消息给订阅者，触发相应监听回调。当创建Vue实例时，vue会遍历data选项的属性，利用Objet.defineProperty为属性添加getter和setter对数据的读取进行劫持（getter用来依赖收集，setter用来派发更新），并且在内部追踪依赖，在属性被访问和修改时通知变化。每个组件实例会有对应的watcher实例，在组件渲染的过程中记录依赖的所有数据属性（进行依赖收集，还有computed watcher，user watcher实例），之后依赖项被该改动时，setter方法会通知依赖与此data的watcher实例重新计算（派发更新），从而使它关联的组件重新渲染</p>
</blockquote>
<h3 id="computed-和-watch"><a href="#computed-和-watch" class="headerlink" title="computed 和 watch"></a>computed 和 watch</h3><blockquote>
<p><strong>watch 属性监听</strong> 是一个对象，键是需要观察的属性，值是对应回调函数，主要用来监听某些特定数据的变化，从而进行某些具体的业务逻辑操作,监听属性的变化，需要在数据变化时执行异步或开销较大的操作时使用。watch 是异步的，会在当前代码执行完成后执行</p>
</blockquote>
<blockquote>
<p><strong>computed 计算属性</strong> 属性的结果会被缓存，当computed中的函数所依赖的属性没有发生改变的时候，那么调用当前函数的时候结果会从缓存中读取。除非依赖的响应式属性变化时才会重新计算，主要当做属性来使用 computed中的函数必须用return返回最终的结果 computed更高效，优先使用。data 不改变，computed 不更新。computed 是同步的</p>
</blockquote>
<h3 id="mixin"><a href="#mixin" class="headerlink" title="mixin"></a>mixin</h3><blockquote>
<p><strong>优点：</strong>mixin 项目变得复杂的时候，多个组件间有重复的逻辑就会用到mixin</p>
</blockquote>
<blockquote>
<p><strong>缺点：</strong>多mixin可能会造成命名冲突；mixin和组件可能出现多对多的关系，使得项目复杂度变高</p>
</blockquote>
<h3 id="vue-hook"><a href="#vue-hook" class="headerlink" title="vue hook"></a>vue hook</h3><blockquote>
<p>vue hook：hook其实就是一种回调函数，这种回调函数的名称已经被固定，内容不固定，且函数名称作为了一个接口被暴露出去</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 不适用 hook</span></span><br><span class="line">data () &#123;</span><br><span class="line">	<span class="keyword">return</span> &#123;</span><br><span class="line">		timer: <span class="literal">null</span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line">mounted () &#123;</span><br><span class="line">	<span class="built_in">this</span>.timer = <span class="built_in">setInterval</span>(<span class="function">() =&gt;</span> &#123; .... &#125;, <span class="number">1000</span>)</span><br><span class="line">&#125;</span><br><span class="line">beforeDestory () &#123;</span><br><span class="line">	<span class="built_in">clearInterval</span>(<span class="built_in">this</span>.timer)</span><br><span class="line">	<span class="built_in">this</span>.timer = <span class="literal">null</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 hook</span></span><br><span class="line">mounted () &#123;</span><br><span class="line">	<span class="keyword">const</span> timer = <span class="built_in">setInterval</span>(<span class="function">() =&gt;</span> &#123; .... &#125;, <span class="number">1000</span>)</span><br><span class="line">	<span class="built_in">this</span>.$once(<span class="string">&#x27;hook:beforeDestory&#x27;</span>, <span class="function">() =&gt;</span> <span class="built_in">clearInterval</span>(timer))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>子组件内部监听（如上实例代码）</p>
</blockquote>
<blockquote>
<p>父组件对子组件监听：当组件内的生命周期函数在执行结束后 $emit 的自定义事件。不仅仅可以在组件内被 $on 接收，vue 的语法决定了这些事件也可以被父组件 v-on 监听到</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 场景：在父组件将数据传递到子组件之前，让子组件页面 loading，当数据渲染完成后，让子组件页面关闭 loading （在父组件通过控制子组件的生命周期来控制 loading 的显示）</span></span><br><span class="line">&lt;v-chart</span><br><span class="line">	@hook:mounted=<span class="string">&quot;loading = false&quot;</span></span><br><span class="line">	@hook:beforeUpdated=<span class="string">&quot;loading = true&quot;</span></span><br><span class="line">	@hook:update=<span class="string">&quot;loading = false&quot;</span></span><br><span class="line">	:data=<span class="string">&quot;data&quot;</span></span><br><span class="line">&gt;&lt;/v-chart&gt;</span><br></pre></td></tr></table></figure>

<h3 id="hash-和-history-的区别"><a href="#hash-和-history-的区别" class="headerlink" title="hash 和 history 的区别"></a>hash 和 history 的区别</h3><blockquote>
<p>hash路由在地址栏URL上有#，用 window.location.hash 读取。而history路由没有会好看一点</p>
</blockquote>
<blockquote>
<p>我们进行回车刷新操作，hash路由会加载到地址栏对应的页面，而history路由一般就404报错了（因为路径不是真实存在的，刷新相当于网络请求，如果后端没有配置，则会报404）</p>
</blockquote>
<blockquote>
<p>3.hash路由支持低版本的浏览器，而history路由是HTML5新增的API</p>
</blockquote>
<blockquote>
<p>4.hash的特点在于它虽然出现在了URL中，但是不包括在http请求中，所以对于后端是没有一点影响的，所以改变hash不会重新加载页面，所以这也是单页面应用的必备</p>
</blockquote>
<blockquote>
<p>5.history运用了浏览器的历史记录栈，之前有back,forward,go方法</p>
</blockquote>
<h3 id="vuex-刷新数据丢失怎么办？"><a href="#vuex-刷新数据丢失怎么办？" class="headerlink" title="vuex 刷新数据丢失怎么办？"></a>vuex 刷新数据丢失怎么办？</h3><blockquote>
<p>丢失的原因：页面刷新，页面会销毁之前的资源，重新请求，vuex 里面的数据会被初始化，就导致了数据丢失</p>
</blockquote>
<blockquote>
<p>解决方法：使用本地存储；使用插件 vuex-persistedstate，可以持久化 state</p>
</blockquote>
<h3 id="vuex-核心属性"><a href="#vuex-核心属性" class="headerlink" title="vuex 核心属性"></a>vuex 核心属性</h3><blockquote>
<p>state：定义所需要的数据</p>
</blockquote>
<blockquote>
<p>getter：从 store 中派生出一些状态，具有缓存特性，只有依赖的值发生变化时才会重新计算</p>
</blockquote>
<blockquote>
<p>mutation：更改 state 中的数据，同步</p>
</blockquote>
<blockquote>
<p>action：可以触发 mutation，异步操作</p>
</blockquote>
<blockquote>
<p>module：模块化</p>
</blockquote>
<h3 id="vue-项目做过什么优化"><a href="#vue-项目做过什么优化" class="headerlink" title="vue 项目做过什么优化"></a>vue 项目做过什么优化</h3><blockquote>
<p>v-if 和 v-show 区分使用场景</p>
</blockquote>
<blockquote>
<p>computed 和 watch 区分使用场景</p>
</blockquote>
<blockquote>
<p>图片资源懒加载；路由懒加载；第三方资源按需引入</p>
</blockquote>
<blockquote>
<p>通过webpack对图片进行压缩；提取公共代码等</p>
</blockquote>
<blockquote>
<p>使用 CDN，使用浏览器缓存等等</p>
</blockquote>
<h3 id="如何做首屏优化"><a href="#如何做首屏优化" class="headerlink" title="如何做首屏优化"></a>如何做首屏优化</h3><blockquote>
<p>图片懒加载，图片压缩；css 模块化加载；减少请求次数；路由懒加载；优化 webpack 的打包体积;减少重排重绘</p>
</blockquote>
<h3 id="vue-单页面应用的优缺点"><a href="#vue-单页面应用的优缺点" class="headerlink" title="vue 单页面应用的优缺点"></a>vue 单页面应用的优缺点</h3><blockquote>
<p>优点：用户体验好，内容的改变不需要重新加载整个页面；缺点：初次加载耗时长</p>
</blockquote>
<h3 id="vue-路由守卫"><a href="#vue-路由守卫" class="headerlink" title="vue 路由守卫"></a>vue 路由守卫</h3><blockquote>
<p>全局路由守卫：beforeEach()，afterEach()</p>
</blockquote>
<blockquote>
<p>组件守卫：beforeRouteEnter()，beforeRouteLeave()</p>
</blockquote>
<blockquote>
<p>路由守卫：beforeEnter()</p>
</blockquote>
<blockquote>
<p>完整的路由导航：导航被触发，在失活的组件里面调用 beforeRouteLeave，然后调用全局路由守卫beforeEach，在路由配置中调用 beforeEnter，然后解析异步路由组件，在被激活的组件中调用beforeRouteEnter，导航被确认，调用全局的 afterEach，触发 DOM 更新</p>
</blockquote>
<h3 id="vue3-和-vue2-的区别（或者新增的特性）"><a href="#vue3-和-vue2-的区别（或者新增的特性）" class="headerlink" title="vue3 和 vue2 的区别（或者新增的特性）"></a>vue3 和 vue2 的区别（或者新增的特性）</h3><blockquote>
<p>vue3 增加了一个函数 setup()，用于创建响应式变量和方法；不能是一个 async 函数，因为setup() 要求返回的是一个对象，如果是一个 async 函数的话，就变为返回一个 promise 了，模板中就无法使用了；setup() 是围绕 beforeCreated 和 Created 两个生命周期运行的</p>
</blockquote>
<blockquote>
<p>接收 props</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">  <span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    props: &#123;&#125;</span><br><span class="line">    <span class="function"><span class="title">setup</span>(<span class="params">props, context</span>)</span> &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(props)</span><br><span class="line">      &#123;<span class="comment">/* context: 上下文对象 用于接收 attributes 透传, 如 context.attrs */</span>&#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 方法二</span></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">  <span class="keyword">const</span> props = defineProps(&#123;</span><br><span class="line">    title: string</span><br><span class="line">  &#125;)</span><br><span class="line">  <span class="built_in">console</span>.log(props.title)</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>触发 emit</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">  <span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    props: &#123;&#125;</span><br><span class="line">    <span class="function"><span class="title">setup</span>(<span class="params">props, context</span>)</span> &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(props)</span><br><span class="line">      context.emit(xxxxx) <span class="comment">// 触发自定义事件</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">  <span class="keyword">const</span> props = defineProps(&#123;</span><br><span class="line">    title: string</span><br><span class="line">  &#125;)</span><br><span class="line">  <span class="keyword">const</span> emit = defineEmits([<span class="string">&#x27;change&#x27;</span>, <span class="string">&#x27;delete&#x27;</span>])</span><br><span class="line">  emit(<span class="string">&#x27;change&#x27;</span>, <span class="number">1</span>)</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h3 id="vue3-生命周期"><a href="#vue3-生命周期" class="headerlink" title="vue3 生命周期"></a>vue3 生命周期</h3><blockquote>
<p>onBeforeMount()、onMounted()、onBeforeUpdate、onUpdated、onBeforeUnmount、onUnmounted（相对于 vue2，少了beforeCreate,created）</p>
</blockquote>
<h3 id="vue3-组件通信"><a href="#vue3-组件通信" class="headerlink" title="vue3 组件通信"></a>vue3 组件通信</h3><blockquote>
<p>父子组件通信: props 和 emit</p>
</blockquote>
<blockquote>
<p>ref：通过 ref 获取子组件中的属性和方法。因为再 setup() 中没有 this，所以需要使用getCurrentInstance和defineExpose</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">&lt;div&gt;</span><br><span class="line">  &lt;Child ref=<span class="string">&quot;child&quot;</span> /&gt;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="title">setup</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">    <span class="keyword">import</span> &#123; getCurrentInstance &#125; form <span class="string">&#x27;@vue/runtime-core&#x27;</span> </span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> currentInstance = getCurrentInstance();</span><br><span class="line"></span><br><span class="line">    currentInstance.$refs.child.aaa()</span><br><span class="line">  &#125;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 子组件</span></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">  <span class="keyword">const</span> aaa = <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="number">11111</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  &#123;<span class="comment">/* 通过&lt;script setup&gt;语法糖的写法，其组件是默认关闭的，也就是说如果是通过$refs或者$parents来访问子组件中定义的值是拿不到的，必须通过defineExpose向外暴露你想获取的值才行 */</span>&#125;</span><br><span class="line">  defineExpose(&#123;</span><br><span class="line">    aaa</span><br><span class="line">  &#125;)</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>project/inject: Vue 中提供的一对 API。无论层级多深，API 都可以实现父组件到子孙组件的数据传递。</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">provide(<span class="string">&#x27;value&#x27;</span>, <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 子组件</span></span><br><span class="line"><span class="keyword">const</span> a = inject(<span class="string">&#x27;value&#x27;</span>)</span><br></pre></td></tr></table></figure>

<blockquote>
<p>attributes 透传（相当于 $attrs 和 $lisence</p>
</blockquote>
<blockquote>
<p>vuex</p>
</blockquote>
<h1 id="react"><a href="#react" class="headerlink" title="react"></a>react</h1><h3 id="react-组件通信"><a href="#react-组件通信" class="headerlink" title="react 组件通信"></a>react 组件通信</h3><blockquote>
<p><strong>父组件向子组件通信：</strong>通过 props 向子组件通信</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> parant = <span class="function">() =&gt;</span> &#123;</span><br><span class="line">	<span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">child</span> <span class="attr">name</span>=<span class="string">&quot;子组件&quot;</span> /&gt;</span></span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> Child = <span class="function"><span class="params">props</span> =&gt;</span> &#123;</span><br><span class="line">	consoole.log(props)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>子组件向父组件传参</strong> porps + 回调的方式</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 子组件: Child</span></span><br><span class="line"><span class="keyword">const</span> Child = <span class="function"><span class="params">props</span> =&gt;</span>&#123;</span><br><span class="line">  <span class="keyword">const</span> cb = <span class="function"><span class="params">msg</span> =&gt;</span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="function">()=&gt;</span>&#123;</span><br><span class="line">          props.callback(msg)</span><br><span class="line">      &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">      &lt;button onClick=&#123;<span class="function">() =&gt;</span> cb(<span class="string">&#x27;11111&#x27;</span>)&#125;&gt;点击传参&lt;/button&gt;</span><br><span class="line">  )</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 父组件 Parent</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Parent</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="title">callback</span>(<span class="params">msg</span>)</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(msg)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="title">render</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">Child</span> <span class="attr">callback</span>=<span class="string">&#123;this.callback.bind(this)&#125;</span>&gt;</span><span class="tag">&lt;/<span class="name">Child</span>&gt;</span></span>    </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>跨级组件通信：</strong>即父组件向子组件的子组件通信，向更深层子组件通信，使用  context</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// context方式实现跨级组件通信 </span></span><br><span class="line"><span class="comment">// Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> BatteryContext = createContext();</span><br><span class="line"></span><br><span class="line"><span class="comment">//  子组件的子组件 </span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">GrandChild</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="title">render</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> (</span><br><span class="line">            &lt;BatteryContext.Consumer&gt;</span><br><span class="line">                &#123;</span><br><span class="line">                    color =&gt; <span class="xml"><span class="tag">&lt;<span class="name">h1</span> <span class="attr">style</span>=<span class="string">&#123;&#123;</span>&quot;<span class="attr">color</span>&quot;<span class="attr">:color</span>&#125;&#125;&gt;</span>我是红色的:&#123;color&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></span><br><span class="line">                &#125;</span><br><span class="line">            &lt;/BatteryContext.Consumer&gt;</span><br><span class="line">        ) </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//  子组件</span></span><br><span class="line"><span class="keyword">const</span> Child = <span class="function">() =&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">        &lt;GrandChild/&gt;</span><br><span class="line">    )</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 父组件</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Parent</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">      state = &#123;</span><br><span class="line">          color:<span class="string">&quot;red&quot;</span></span><br><span class="line">      &#125;</span><br><span class="line">      <span class="function"><span class="title">render</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">          <span class="keyword">const</span> &#123;color&#125; = <span class="built_in">this</span>.state</span><br><span class="line">          <span class="keyword">return</span> (</span><br><span class="line">          &lt;BatteryContext.Provider value=&#123;color&#125;&gt;</span><br><span class="line">              &lt;Child&gt;&lt;/Child&gt;</span><br><span class="line">          &lt;/BatteryContext.Provider&gt; </span><br><span class="line">          )</span><br><span class="line">      &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>非嵌套关系可以使用 redux</strong></p>
</blockquote>
<h3 id="setState-既存在异步情况也存在同步情况"><a href="#setState-既存在异步情况也存在同步情况" class="headerlink" title="setState 既存在异步情况也存在同步情况"></a>setState 既存在异步情况也存在同步情况</h3><blockquote>
<p>假如所有setState是同步的，意味着每执行一次setState时（有可能一个同步代码中，多次setState），都重新vnode diff + dom修改，这对性能来说是极为不好的。如果是异步，则可以把一个同步代码中的多个setState合并成一次组件更新。所以默认是异步的，但是在一些情况下是同步的</p>
</blockquote>
<blockquote>
<p><strong>为什么要做异步操作呢？</strong>一般来说，都是为了性能优化，减少渲染的次数：如果是调用 setState 都进行一次更新的话，render 函数就会被频繁调用，异步操作能将 setState 合并后更新，所以要做异步操作</p>
</blockquote>
<blockquote>
<p><strong>异步：</strong>在 react 事件，生命周期中是异步操作</p>
</blockquote>
<blockquote>
<p><strong>同步：</strong>在 setTimeout 或者自定义事件中，都是同步操作</p>
</blockquote>
<blockquote>
<p><strong>具体原因：</strong>可以自己查看源码</p>
</blockquote>
<h3 id="setState-批量更新的过程是什么？"><a href="#setState-批量更新的过程是什么？" class="headerlink" title="setState 批量更新的过程是什么？"></a>setState 批量更新的过程是什么？</h3><blockquote>
<p>调用 setState 时，组件的 state 并不会立即改变， setState 只是把要修改的 state 放入一个队列， React 会优化真正的执行时机，并出于性能原因，会将 React 事件处理程序中的多次React 事件处理程序中的多次 setState 的状态修改合并成一次状态修改。 最终更新只产生一次组件及其子组件的重新渲</p>
</blockquote>
<h3 id="React中有使用过getDefaultProps吗？它有什么作用？"><a href="#React中有使用过getDefaultProps吗？它有什么作用？" class="headerlink" title="React中有使用过getDefaultProps吗？它有什么作用？"></a>React中有使用过getDefaultProps吗？它有什么作用？</h3><blockquote>
<p>通过实现组件的getDefaultProps，对属性设置默认值（ES5的写法）</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> ShowTitle = React.createClass(&#123;</span><br><span class="line">  getDefaultProps:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span>&#123;</span><br><span class="line">      title : <span class="string">&quot;React&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  render : <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">h1</span>&gt;</span>&#123;this.props.title&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>


<h3 id="React中的setState和replaceState的区别是什么？"><a href="#React中的setState和replaceState的区别是什么？" class="headerlink" title="React中的setState和replaceState的区别是什么？"></a>React中的setState和replaceState的区别是什么？</h3><blockquote>
<p> setState 是修改其中的部分状态，相当于 Object.assign，只是覆盖，不会减少原来的状态。而replaceState 是完全替换原来的状态，相当于赋值，将原来的 state 替换为另一个对象，如果新状态属性减少，那么 state 中就没有这个状态了</p>
</blockquote>
<h3 id="什么是-context？为什么-react-不推荐优先考虑使用-context-？"><a href="#什么是-context？为什么-react-不推荐优先考虑使用-context-？" class="headerlink" title="什么是 context？为什么 react 不推荐优先考虑使用  context ？"></a>什么是 context？为什么 react 不推荐优先考虑使用  context ？</h3><blockquote>
<p><strong>context：</strong>提供了一种在组件之间共享此类值的方式，而不必显式地通过组件树的逐层传递 props，即可以实现跨层级数据传递</p>
</blockquote>
<blockquote>
<p><strong>为什么不推荐使用 context：</strong>Context目前还处于实验阶段，可能会在后面的发行版本中有很大的变化，并且context的更新需要通过setState()触发，但是这并不是很可靠的，Context支持跨组件的访问，但是如果中间的子组件通过一些方法不影响更新，比如 shouldComponentUpdate() 返回false 那么不能保证Context的更新一定可以使用</p>
</blockquote>
<h3 id="React组件的state和props有什么区别？"><a href="#React组件的state和props有什么区别？" class="headerlink" title="React组件的state和props有什么区别？"></a>React组件的state和props有什么区别？</h3><blockquote>
<p><strong>props：</strong>props是一个从外部传进组件的参数，主要作为就是从父组件向子组件传递数据，它具有可读性和不变性，只能通过外部组件主动传入新的props来重新渲染子组件，否则子组件的props以及展现形式不会改变。</p>
</blockquote>
<blockquote>
<p><strong>state：</strong>state的主要作用是用于组件保存、控制以及修改自己的状态，它只能在constructor中初始化，它算是组件的私有属性，不可通过外部访问和修改，只能通过组件内部的this.setState来修改，修改state属性会导致组件的重新渲染。</p>
</blockquote>
<blockquote>
<p><strong>区别：</strong>props 是传递给组件的，是不可修改的；state 是在组件内被组件自己管理的，可以通过 setState 进行修改</p>
</blockquote>
<h3 id="在React中组件的props改变时更新组件的有哪些方法？"><a href="#在React中组件的props改变时更新组件的有哪些方法？" class="headerlink" title="在React中组件的props改变时更新组件的有哪些方法？"></a>在React中组件的props改变时更新组件的有哪些方法？</h3><blockquote>
<p>使用 getDerivedStateFromProps，getDerivedStateFromProps 是一个静态函数，通过参数提供的nextProps以及prevState来进行判断，根据新传入的props来映射到state</p>
</blockquote>
<h3 id="React中怎么检验props？验证props的目的是什么？"><a href="#React中怎么检验props？验证props的目的是什么？" class="headerlink" title="React中怎么检验props？验证props的目的是什么？"></a>React中怎么检验props？验证props的目的是什么？</h3><blockquote>
<p>React为我们提供了PropTypes以供验证使用。当我们向Props传入的数据无效（向Props传入的数据类型和验证的数据类型不符）就会在控制台发出警告信息。它可以避免随着应用越来越复杂从而出现的问题。并且，它还可以让程序变得更易读</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> PropTypes <span class="keyword">from</span> <span class="string">&#x27;prop-types&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Greeting</span> <span class="keyword">extends</span> <span class="title">React</span>.<span class="title">Component</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">render</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      &lt;h1&gt;Hello, &#123;<span class="built_in">this</span>.props.name&#125;&lt;/h1&gt;</span><br><span class="line">    );</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Greeting.propTypes = &#123;</span><br><span class="line">  name: PropTypes.string</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>


<h3 id="react-生命周期"><a href="#react-生命周期" class="headerlink" title="react 生命周期"></a>react 生命周期</h3><blockquote>
<p><strong>挂载阶段：</strong>constructor()：用于初始化 state，事件处理函数绑定实例；componentDidMount()：在组件挂载后（插入 DOM 树中）立即调用，可以发送请求获取数据；<strong>更新阶段：</strong>componentDidUpdate()：在更新后会被立即调用。首次渲染不会执行此方法；<strong>卸载阶段：</strong>componentWillUnmount()：在组件卸载及销毁之前直接调用；不常用的生命周期：shouldComponentUpdate()：根据返回值，判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染，仅作为性能优化的方式；getDerivedStateFromProps()：会在调用 render 方法之前调用，并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state，如果返回 null 则不更新任何内容；</p>
</blockquote>
<h3 id="react-事件绑定原理（事件机制）"><a href="#react-事件绑定原理（事件机制）" class="headerlink" title="react 事件绑定原理（事件机制）"></a>react 事件绑定原理（事件机制）</h3><blockquote>
<p><strong>原理：</strong>当用户在为onClick添加函数时，React并没有将Click时间绑定在DOM上面。而是在document处监听所有支持的事件，当事件发生并冒泡至document处时，React将事件内容封装交给中间层SyntheticEvent（中间层的作用是：负责所有事件合成），所以当事件触发的时候，会使用统一的分发函数dispatchEvent将指定函数执行。</p>
</blockquote>
<blockquote>
<p>因此如果不想要是事件冒泡的话应该调用event.preventDefault()方法，而不是调用event.stopProppagation()方法</p>
</blockquote>
<h3 id="react-事件和普通的事件有什么区别？"><a href="#react-事件和普通的事件有什么区别？" class="headerlink" title="react 事件和普通的事件有什么区别？"></a>react 事件和普通的事件有什么区别？</h3><blockquote>
<p>对于事件名称命名方式，原生事件为全小写，react 事件采用小驼峰；</p>
</blockquote>
<blockquote>
<p>对于事件函数处理语法，原生事件为字符串，react 事件为函数；</p>
</blockquote>
<blockquote>
<p>react 事件不能采用 return false 的方式来阻止浏览器的默认行为，而必须要地明确地调用preventDefault()来阻止默认行为</p>
</blockquote>
<blockquote>
<p>合成事件是 react 模拟原生 DOM 事件所有能力的一个事件对象，<strong>合成事件的优点：</strong>兼容所有浏览器，更好的跨平台；将事件统一存放在一个数组，避免频繁的新增与删除（垃圾回收）；方便 react 统一管理和事务机制</p>
</blockquote>
<blockquote>
<p><strong>事件的执行顺序为</strong>原生事件先执行，合成事件后执行，合成事件会冒泡绑定到 document 上，所以尽量避免原生事件与合成事件混用，如果原生事件阻止冒泡，可能会导致合成事件不执行，因为需要冒泡到document 上合成事件才会执行</p>
</blockquote>
<h3 id="react-中的-key-有什么作用"><a href="#react-中的-key-有什么作用" class="headerlink" title="react 中的 key 有什么作用"></a>react 中的 key 有什么作用</h3><blockquote>
<p>react利用key来识别组件，它是一种身份标识标识，相同的key react认为是同一个组件，这样后续相同的key对应组件都不会被创建</p>
</blockquote>
<blockquote>
<p>有了key属性后，就可以与组件建立了一种对应关系，react根据key来决定是销毁重新创建组件还是更新组件</p>
</blockquote>
<blockquote>
<p>key相同，若组件属性有所变化，则react只更新组件对应的属性；没有变化则不更新</p>
</blockquote>
<h3 id="调用-setState-之后发生了什么"><a href="#调用-setState-之后发生了什么" class="headerlink" title="调用 setState 之后发生了什么"></a>调用 setState 之后发生了什么</h3><blockquote>
<p>在代码中调用 setState 函数之后，React 会将传入的参数对象与组件当前的状态合并，然后触发所谓的调和过程</p>
</blockquote>
<blockquote>
<p>经过调和过程，React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面；</p>
</blockquote>
<blockquote>
<p>在 React 得到元素树之后，React 会自动计算出新的树与老树的节点差异，然后根据差异对界面进行最小化重渲染；</p>
</blockquote>
<blockquote>
<p>在差异计算算法中，React 能够相对精确地知道哪些位置发生了改变以及应该如何改变，这就保证了按需更新，而不是全部重新渲染。</p>
</blockquote>
<h3 id="多次触发-setState-，render-会渲染几次？"><a href="#多次触发-setState-，render-会渲染几次？" class="headerlink" title="多次触发 setState ，render 会渲染几次？"></a>多次触发 setState ，render 会渲染几次？</h3><blockquote>
<p>多次setState会合并为一次render，因为setState并不会立即改变state的值，而是将其放到一个任务队列里，最终将多个setState合并，一次性更新页面是。所以，多次调用 setState 只需要关注当前修改的字段即可</p>
</blockquote>
<h3 id="为什么建议传递给-setState的参数是一个callback而不是一个对象？"><a href="#为什么建议传递给-setState的参数是一个callback而不是一个对象？" class="headerlink" title="为什么建议传递给 setState的参数是一个callback而不是一个对象？"></a>为什么建议传递给 setState的参数是一个callback而不是一个对象？</h3><h3 id="react-性能优化是那几个生命周期函数？"><a href="#react-性能优化是那几个生命周期函数？" class="headerlink" title="react 性能优化是那几个生命周期函数？"></a>react 性能优化是那几个生命周期函数？</h3><blockquote>
<p>shouldComponentUpdate这个方法用来判断是否需要调用render方法重新描绘dom。因为dom的描绘非常消耗性能，如果我们能在shouldComponentUpdate方法中能够写出更优化的dom diff算法，可以极大的提高性能</p>
</blockquote>
<h3 id="this-setState之后react做了哪些操作？"><a href="#this-setState之后react做了哪些操作？" class="headerlink" title="this.setState之后react做了哪些操作？"></a>this.setState之后react做了哪些操作？</h3><blockquote>
<p>shouldComponentUpdate</p>
</blockquote>
<blockquote>
<p>componentWillUpdate</p>
</blockquote>
<blockquote>
<p>render</p>
</blockquote>
<blockquote>
<p>componentDidUpdate</p>
</blockquote>
<h3 id="react-虚拟-DOM"><a href="#react-虚拟-DOM" class="headerlink" title="react 虚拟 DOM"></a>react 虚拟 DOM</h3><blockquote>
<p>虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存，利用 dom diff 算法避免了没有必要的 dom 操作，有助于提高性能，并且使用 JavaScript 对象结构表示 DOM 的结构，然后利用这个数创建真正的 DOM 树，插到文档当中当状态变更的时候，重新构造一棵新的对象树，然后用新的树和旧的树进行比较，将差异化部分更新到真实的 DOM 上。</p>
</blockquote>
<h3 id="函数组件和类组件的区别？"><a href="#函数组件和类组件的区别？" class="headerlink" title="函数组件和类组件的区别？"></a>函数组件和类组件的区别？</h3><blockquote>
<p><strong>类组件：</strong>可以有其它特性，如状态 state，生命周期钩子，this 等</p>
</blockquote>
<blockquote>
<p><strong>函数组件：</strong>无状态组件，页面接收 props 用于渲染页面，无 this</p>
</blockquote>
<blockquote>
<p><strong>优先使用函数组件：</strong>因为类组件使用的时候需要实例化，而函数组件只需要返回结果即可</p>
</blockquote>
<h3 id="react-中的-refs"><a href="#react-中的-refs" class="headerlink" title="react 中的 refs"></a>react 中的 refs</h3><blockquote>
<p><strong>Refs：</strong>提供了一种访问 render 方法中创建的 DOM　节点或者　React　元素的方法，适用于类组件</p>
</blockquote>
<blockquote>
<p><strong>useRef：</strong>函数组件使用 useRef() hooks 来获取 DOM　节点</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">UnControlledForm</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">  handleSubmit = <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&quot;Input Value: &quot;</span>, <span class="built_in">this</span>.input.value)</span><br><span class="line">  &#125;</span><br><span class="line">  render () &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      &lt;form onSubmit=&#123;<span class="built_in">this</span>.handleSubmit&#125;&gt;</span><br><span class="line">        &lt;input</span><br><span class="line">          type=<span class="string">&#x27;text&#x27;</span></span><br><span class="line">          ref=&#123;<span class="function">(<span class="params">input</span>) =&gt;</span> <span class="built_in">this</span>.input = input&#125; /&gt;</span><br><span class="line">        &lt;button type=<span class="string">&#x27;submit&#x27;</span>&gt;Submit&lt;/button&gt;</span><br><span class="line">      &lt;/form&gt;</span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<h3 id="在构造函数调用-super-并将-props-作为参数传入的作用是啥？"><a href="#在构造函数调用-super-并将-props-作为参数传入的作用是啥？" class="headerlink" title="在构造函数调用 super 并将 props 作为参数传入的作用是啥？"></a>在构造函数调用 super 并将 props 作为参数传入的作用是啥？</h3><blockquote>
<p>在调用 super() 方法之前，子类构造函数无法使用this引用，ES6 子类也是如此。将 props 参数传递给 super() 调用的主要原因是在子构造函数中能够通过this.props来获取传入的 props。</p>
</blockquote>
<h3 id="什么是-jsx-？"><a href="#什么是-jsx-？" class="headerlink" title="什么是 jsx ？"></a>什么是 jsx ？</h3><blockquote>
<p><strong>jsx：</strong>JSX 是 JavaScript 的语法扩展，将原始 HTML 模板嵌入到 JS 代码中。JSX 本身不能被浏览器读取，必须使用 Babel 和 webpack 等工具转换为传统的 JS </p>
</blockquote>
<h3 id="为什么不能直接修改-state-？"><a href="#为什么不能直接修改-state-？" class="headerlink" title="为什么不能直接修改 state ？"></a>为什么不能直接修改 state ？</h3><blockquote>
<p>使用 state 直接修改状态，组件不会重新渲染。在改变 state 的时候，如果其它地方也在修改 state，尤其是在异步当中，最后就有可能出现一些其它问题。</p>
</blockquote>
<h3 id="为什么要使用-setState-来更改状态"><a href="#为什么要使用-setState-来更改状态" class="headerlink" title="为什么要使用 setState 来更改状态"></a>为什么要使用 setState 来更改状态</h3><blockquote>
<p>因为我们修改了状态state的时候,希望React根据最新的state来重新渲染界面,直接修改的方式,react并不会知道状态发生了改变，组件不会重新发生渲染。所以必须通过setState来告知react状态的改变。setState是继承自Component,当我们调用setState的时候,会重新执行render方法</p>
</blockquote>
<h3 id="使用-React-Hooks-好处是啥？"><a href="#使用-React-Hooks-好处是啥？" class="headerlink" title="使用 React Hooks 好处是啥？"></a>使用 React Hooks 好处是啥？</h3><blockquote>
<p>Hooks 通常支持提取和重用跨多个组件通用的有状态逻辑，而无需承担高阶组件或渲染 props 的负担。Hooks 可以轻松地操作函数组件的状态，而不需要将它们转换为类组件</p>
</blockquote>
<h3 id="为什么类方法需要绑定到类实例？"><a href="#为什么类方法需要绑定到类实例？" class="headerlink" title="为什么类方法需要绑定到类实例？"></a>为什么类方法需要绑定到类实例？</h3><blockquote>
<p><strong>根本原因是：</strong>react中的 DOM　是虚拟　DOM，JSX　是的 <code>React.createElement(component, props, ...children)</code>的语法糖，我们在 HTML 上绑定事件，最终会解析成 <code> React.createElement()</code>来创建该 HTML 标签和事件，此时的事件，如 onClick={function} 本事就是一个中间变量，事件对应的函数又是作为一个回调函数传给另一个函数，最终就导致了 this 指向丢失，所以必须要绑定 this</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 原代码</span></span><br><span class="line"><span class="function"><span class="title">render</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">	<span class="keyword">return</span> (</span><br><span class="line">		&lt;div onClick=&#123;<span class="built_in">this</span>.handleClick&#125;&gt;点击&lt;/div&gt;</span><br><span class="line">	)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 会被解析为</span></span><br><span class="line"><span class="function"><span class="title">render</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">	<span class="keyword">return</span> React.createElement(</span><br><span class="line">		<span class="string">&#x27;a&#x27;</span>,</span><br><span class="line">		&#123;</span><br><span class="line">			onClick: <span class="built_in">this</span>.handleClick</span><br><span class="line">		&#125;,</span><br><span class="line">		<span class="string">&#x27;点击&#x27;</span></span><br><span class="line">	)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 所以 this 指向才会丢失了</span></span><br></pre></td></tr></table></figure>


<h3 id="如何避免组件的重新渲染？"><a href="#如何避免组件的重新渲染？" class="headerlink" title="如何避免组件的重新渲染？"></a>如何避免组件的重新渲染？</h3><blockquote>
<p>**React.memo():**这可以防止不必要地重新渲染函数组件</p>
</blockquote>
<blockquote>
<p>**PureComponent:**这可以防止不必要地重新渲染类组件</p>
</blockquote>
<blockquote>
<p><strong>shouldComponentUpdate：</strong>设置为 false</p>
</blockquote>
<blockquote>
<p>这两种方法都依赖于对传递给组件的props的浅比较，如果 props 没有改变，那么组件将不会重新渲染。虽然这两种工具都非常有用，但是浅比较会带来额外的性能损失，因此如果使用不当，这两种方法都会对性能产生负面影响</p>
</blockquote>
<blockquote>
<p>通过使用 React Profiler（react 性能审查工具），可以在使用这些方法前后对性能进行测量，从而确保通过进行给定的更改来实际改进性能</p>
</blockquote>
<h3 id="什么是纯函数"><a href="#什么是纯函数" class="headerlink" title="什么是纯函数"></a>什么是纯函数</h3><blockquote>
<p>纯函数是不依赖并且不会在其作用域之外修改变量状态的函数。本质上，纯函数始终在给定相同参数的情况下返回相同结果</p>
</blockquote>
<h3 id="如何在React中使用innerHTML"><a href="#如何在React中使用innerHTML" class="headerlink" title="如何在React中使用innerHTML"></a>如何在React中使用innerHTML</h3><blockquote>
<p>增加dangerouslySetInnerHTML属性，并且传入对象的属性名叫_html</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Component</span>(<span class="params">props</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">dangerouslySetInnerHTML</span>=<span class="string">&#123;&#123;_html:</span>&#x27;&lt;<span class="attr">span</span>&gt;</span>你好<span class="tag">&lt;/<span class="name">span</span>&gt;</span>&#x27;&#125;&#125;&gt;</span></span><br><span class="line"><span class="xml">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<h3 id="哪些方法会触发-React-重新渲染？重新渲染-render-会做些什么？"><a href="#哪些方法会触发-React-重新渲染？重新渲染-render-会做些什么？" class="headerlink" title="哪些方法会触发 React 重新渲染？重新渲染 render 会做些什么？"></a>哪些方法会触发 React 重新渲染？重新渲染 render 会做些什么？</h3><blockquote>
<p><strong>触发 render重新渲染：</strong>setState（）方法被调用；props 发生改变；父组件重新渲染(即使传入子组件的 props 未发生改变，子组件也会重新渲染；)</p>
</blockquote>
<blockquote>
<p><strong>重新渲染会发生什么：</strong>会对比新旧节点，将差异化部分保存到要给对象中，然后遍历差异对象，根据差异的类型和对应规则更新 DOM 节点</p>
</blockquote>
<h3 id="对-React-中-Fragment-的理解以及使用场景"><a href="#对-React-中-Fragment-的理解以及使用场景" class="headerlink" title="对 React 中 Fragment 的理解以及使用场景"></a>对 React 中 Fragment 的理解以及使用场景</h3><blockquote>
<p>在React中，组件返回的元素只能有一个根元素。为了不添加多余的DOM节点，我们可以使用Fragment标签来包裹所有的元素，Fragment标签不会渲染出任何元素</p>
</blockquote>
<h3 id="react-中如何获取-DOM-节点"><a href="#react-中如何获取-DOM-节点" class="headerlink" title="react 中如何获取 DOM 节点"></a>react 中如何获取 DOM 节点</h3><blockquote>
<p>通过 ref 或者 React.createRef()</p>
</blockquote>
<h3 id="react-可以在-render-阶段中访问-refs-吗"><a href="#react-可以在-render-阶段中访问-refs-吗" class="headerlink" title="react 可以在 render 阶段中访问 refs 吗"></a>react 可以在 render 阶段中访问 refs 吗</h3><blockquote>
<p>不可以，因为 render 阶段 DOM 还没有生成，无法获取 DOM</p>
</blockquote>
<h3 id="什么是受控组件和非受控组件？"><a href="#什么是受控组件和非受控组件？" class="headerlink" title="什么是受控组件和非受控组件？"></a>什么是受控组件和非受控组件？</h3><blockquote>
<p><strong>受控组件：</strong>在使用表单来收集用户输入时，例如<input><select><textearea>等元素都要绑定一个change事件，当表单的状态发生变化，就会触发onChange事件，更新组件的state，这种组件就是受控组件</p>
</blockquote>
<blockquote>
<p><strong>非受控组件：</strong>如果一个表单组件没有value props（单选和复选按钮对应的是checked props）时，就可以称为非受控组件</p>
</blockquote>
<h3 id="React-的构造函数有什么用？是必须的吗？"><a href="#React-的构造函数有什么用？是必须的吗？" class="headerlink" title="React 的构造函数有什么用？是必须的吗？"></a>React 的构造函数有什么用？是必须的吗？</h3><blockquote>
<p><strong>两个作用：</strong>通过将对象分配给 this.state 来初始化本地状态；将事件处理函数绑定到实例上</p>
</blockquote>
<blockquote>
<p>想要在当前组件使用 this，必须在 constructor 方法中调用 super 方法，否则新建实例会报错。这是因为子类没有自己的 this 对象，而是继承父类的 this 对象。</p>
</blockquote>
<h3 id="React-Router的路由有几种模式？"><a href="#React-Router的路由有几种模式？" class="headerlink" title="React-Router的路由有几种模式？"></a>React-Router的路由有几种模式？</h3><blockquote>
<p>React-Router 支持使用 hash（对应 HashRouter）和 browser（对应 BrowserRouter） 两种路由规则， react-router-dom 提供了 BrowserRouter 和 HashRouter 两个组件来实现应用的 UI 和 URL 同步</p>
</blockquote>
<blockquote>
<p>**BrowserRouter:**它使用 HTML5 提供的 history API，其属性如下：basename（所有路由的基准 URL ）</p>
</blockquote>
<blockquote>
<p><strong>HashRouter：</strong></p>
</blockquote>
<h1 id="webpack"><a href="#webpack" class="headerlink" title="webpack"></a>webpack</h1><h3 id="typescript"><a href="#typescript" class="headerlink" title="typescript"></a>typescript</h3><h3 id="any，never，more，void，unknown-的区别"><a href="#any，never，more，void，unknown-的区别" class="headerlink" title="any，never，more，void，unknown 的区别"></a>any，never，more，void，unknown 的区别</h3><blockquote>
<p>any：表示任意类型</p>
</blockquote>
<blockquote>
<p>unknown：表示未知的类型，不能将 unknown 类型的变量赋值给其它变量，否则会报错</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a: unknown;</span><br><span class="line">a = <span class="number">1</span></span><br><span class="line">a = <span class="string">&#x27;1&#x27;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>nerver：表示永远不会返回结果</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 用于抛出错误</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>):<span class="title">nerver</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">&#x27;报错了&#x27;</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>void：表式空，以函数为例，表示没有返回值的函数</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>):<span class="title">void</span> </span>&#123;&#125;</span><br></pre></td></tr></table></figure>

<h3 id=""><a href="#" class="headerlink" title=""></a></h3><h1 id="笔试题"><a href="#笔试题" class="headerlink" title="笔试题"></a>笔试题</h1><h3 id="结果输出"><a href="#结果输出" class="headerlink" title="结果输出"></a>结果输出</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="literal">undefined</span> === <span class="literal">undefined</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">undefined</span> == <span class="literal">undefined</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">null</span> === <span class="literal">null</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">null</span> == <span class="literal">null</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">NaN</span> === <span class="literal">NaN</span>) <span class="comment">// false  为什么都不等，因为 NaN 的意思是：非数（即不是一个数字的意思），NaN 和 NaN 都代表不是一个数字，既然都不是数字，难道就会相同吗，这是不确定的，所以为false</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">NaN</span> == <span class="literal">NaN</span>) <span class="comment">// false</span></span><br><span class="line"><span class="built_in">console</span>.log(&#123;&#125; === &#123;&#125;) <span class="comment">// false 每个对象都是一个单独的引用，指向不同，所以为 false</span></span><br><span class="line"><span class="built_in">console</span>.log(&#123;&#125; == &#123;&#125;) <span class="comment">// false</span></span><br><span class="line"><span class="comment">// 判断对象是否为空，可以使用 Object.keys(&#123;&#125;)，得到要给数组，如果数组长度为0，则是空对象</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">false</span> === <span class="literal">false</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">false</span> == <span class="literal">false</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">false</span> == <span class="string">&#x27;&#x27;</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">false</span> === <span class="string">&#x27;&#x27;</span>) <span class="comment">// false</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="number">0</span> === <span class="string">&#x27;0&#x27;</span>) <span class="comment">// false</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="number">0</span> == <span class="string">&#x27;0&#x27;</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="number">0</span> == <span class="string">&#x27;&#x27;</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="number">0</span> === <span class="string">&#x27;&#x27;</span>) <span class="comment">// false</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">null</span> == <span class="literal">undefined</span>) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="literal">null</span> === <span class="literal">undefined</span>) <span class="comment">// false</span></span><br></pre></td></tr></table></figure>

<h3 id="js-原型链实现继承"><a href="#js-原型链实现继承" class="headerlink" title="js 原型链实现继承"></a>js 原型链实现继承</h3><blockquote>
<p>只要原理：上一个构造函数的实例对象是另一个构造函数的原型对象<br>继承：子类可以继承父类的方法和变量，或者重新父类中的方法；子类也可以添加自己的函数</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">A</span> (<span class="params">name, age</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">this</span>.name = name</span><br><span class="line">  <span class="built_in">this</span>.age = age</span><br><span class="line">&#125;</span><br><span class="line">A.prototype.news = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">`我的名字叫<span class="subst">$&#123;<span class="built_in">this</span>.name&#125;</span>，今年<span class="subst">$&#123;<span class="built_in">this</span>.age&#125;</span>岁`</span>)</span><br><span class="line">&#125;</span><br><span class="line">A.prototype.logc = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">&#x27;log&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">JC</span> (<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line"><span class="comment">// 另一个构造函数指向上一个构造函数（继承对象）的实例对象</span></span><br><span class="line">JC.prototype = <span class="keyword">new</span> A(<span class="string">&#x27;张三&#x27;</span>, <span class="string">&#x27;18&#x27;</span>)</span><br><span class="line"><span class="comment">// 重写父类中的方法</span></span><br><span class="line">JC.prototype.logc = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">&#x27;方法被重写了&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line">JC.prototype.Pfunc = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">&#x27;给原型对象添加自己的函数&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> newFunc = <span class="keyword">new</span> JC()</span><br><span class="line">newFunc.news() <span class="comment">// 输出：我的名字叫张三，今年18岁</span></span><br><span class="line">newFunc.logc() <span class="comment">// 输出：方法被重写了</span></span><br><span class="line"><span class="comment">// 子类通过实例对象添加自己的函数</span></span><br><span class="line">newFunc.ChildFunc = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">&#x27;在实例对象中添加自己的函数&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line">newFunc.ChildFunc()</span><br><span class="line">newFunc.Pfunc()</span><br></pre></td></tr></table></figure>

<h3 id="使用冒泡排序将无序的数组转换为有序的数组"><a href="#使用冒泡排序将无序的数组转换为有序的数组" class="headerlink" title="使用冒泡排序将无序的数组转换为有序的数组"></a>使用冒泡排序将无序的数组转换为有序的数组</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> arr = [<span class="number">1</span>, <span class="number">8</span>, <span class="number">3</span>, <span class="number">0</span>, <span class="number">4</span>, <span class="number">56</span>, <span class="number">92</span>, <span class="number">12</span>]</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> i=<span class="number">0</span>; i &lt; arr.length -<span class="number">1</span>; i++) &#123; <span class="comment">// 数组长度是8，需要比较7次</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> j=<span class="number">0</span>; j &lt; arr.length -<span class="number">1</span> -i; j++) &#123; <span class="comment">// 内循环的次数需要减去外循环的次数，所以需要减 i</span></span><br><span class="line">    <span class="keyword">if</span> (arr[j] &gt; arr[j + <span class="number">1</span>]) &#123; <span class="comment">//从小到大排序</span></span><br><span class="line">      <span class="keyword">var</span> tem = arr[j]</span><br><span class="line">      arr[j] = arr[j + <span class="number">1</span>]</span><br><span class="line">      arr[j + <span class="number">1</span>] = tem</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log(arr)</span><br></pre></td></tr></table></figure>


<h3 id="promise-all-、promise-race"><a href="#promise-all-、promise-race" class="headerlink" title="promise.all()、promise.race()"></a>promise.all()、promise.race()</h3><blockquote>
<p>Promise.all() 接收一个 iterable 类型（ES6的iterable类型有：String、Array、Set、Map、函数的arguments对象、Bom的NodeList对象）作为参数，并且只返回一个 promise 实例；当所有的子Promise都完成，该Promise完成，返回值是全部值的数组；.如果有任何一个失败，该Promise失败，返回值是第一个失败的子Promise的结果</p>
</blockquote>
<blockquote>
<p>使用场景：多个异步合并使用，比如多个接口调用成功后在显示页面</p>
</blockquote>
<blockquote>
<p>Promise.race(iterable) 返回一个 promise，只返回某个最先成功或者最先失败的 promise 的结果</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> str = <span class="string">&quot;1&quot;</span>;</span><br><span class="line"><span class="keyword">let</span> func = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&quot;func&quot;</span>;</span><br><span class="line">&#125;)();</span><br><span class="line"><span class="keyword">let</span> p1 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    resolve(<span class="string">&quot;p1 success&quot;</span>);</span><br><span class="line">  &#125;, <span class="number">1000</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="keyword">let</span> p2 = <span class="built_in">Promise</span>.resolve(<span class="string">&quot;p2 success&quot;</span>);</span><br><span class="line"><span class="keyword">let</span> p3 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">  reject(<span class="string">&quot;p3 error&quot;</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>();</span><br><span class="line">set.add(str);</span><br><span class="line">set.add(func);</span><br><span class="line">set.add(p1);</span><br><span class="line">set.add(p2);</span><br><span class="line"></span><br><span class="line"><span class="built_in">Promise</span>.all(set)</span><br><span class="line">  .then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(res); <span class="comment">// 结果：[&#x27;1&#x27;, &#x27;func&#x27;, &#x27;p1 success&#x27;, &#x27;p2 success&#x27;]</span></span><br><span class="line">  &#125;)</span><br><span class="line">  .catch(<span class="function"><span class="params">err</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(err);</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 如果有一个 promise 失败，则返回失败的 promise 的结果</span></span><br><span class="line">set.add(p3)</span><br><span class="line"><span class="built_in">Promise</span>.all(set)</span><br><span class="line">  .then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(res);</span><br><span class="line">  &#125;)</span><br><span class="line">  .catch(<span class="function"><span class="params">err</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(err); <span class="comment">// 结果：p3 error</span></span><br><span class="line">  &#125;);</span><br></pre></td></tr></table></figure>

<h3 id="计算字符串中出现次数最多的字符"><a href="#计算字符串中出现次数最多的字符" class="headerlink" title="计算字符串中出现次数最多的字符"></a>计算字符串中出现次数最多的字符</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span> (<span class="params">str</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> obj = &#123;&#125;</span><br><span class="line">  <span class="comment">// 记录每个字母出现的次数</span></span><br><span class="line">  str.split(<span class="string">&#x27;&#x27;</span>).forEach(<span class="function"><span class="params">item</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (obj[item]) &#123;</span><br><span class="line">      obj[item]++</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      obj[item] = <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">  <span class="built_in">console</span>.log(obj)</span><br><span class="line">  <span class="keyword">let</span> count = <span class="number">0</span> <span class="comment">// 出现最多字符的次数</span></span><br><span class="line">  <span class="keyword">for</span>(<span class="keyword">let</span> i <span class="keyword">in</span> obj) &#123;</span><br><span class="line">    <span class="keyword">if</span> (count &lt; obj[i]) &#123;</span><br><span class="line">      count = obj[i]</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">let</span> maxStr = []</span><br><span class="line">  <span class="keyword">for</span>(<span class="keyword">let</span> i <span class="keyword">in</span> obj) &#123;</span><br><span class="line">    <span class="keyword">if</span> (count == obj[i]) &#123;</span><br><span class="line">      maxStr.push(i)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">`出现次数最多的字符：<span class="subst">$&#123;maxStr&#125;</span>，出现次数：<span class="subst">$&#123;count&#125;</span>`</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// reduce() 方法接收一个函数作为累加器，数组中的每个值（从左到右）开始缩减，最终计算为一个值</span></span><br><span class="line"><span class="comment">// 语法：array.reduce(function(total, currentValue, currentIndex, arr), initialValue)</span></span><br><span class="line"><span class="comment">// total：必需。初始值, 或者计算结束后的返回值。；currentValue	必需。当前元素；initialValue	可选。传递给函数的初始值</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params">str</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> obj = str.split(<span class="string">&#x27;&#x27;</span>).reduce(<span class="function"><span class="keyword">function</span> (<span class="params">x,y</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (x[y]) &#123; </span><br><span class="line">      x[y]++</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      x[y] = <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> x</span><br><span class="line">  &#125;, &#123;&#125;)</span><br><span class="line">  <span class="keyword">let</span> count = <span class="number">0</span> <span class="comment">// 出现最多字符的次数</span></span><br><span class="line">  <span class="keyword">for</span>(<span class="keyword">let</span> i <span class="keyword">in</span> obj) &#123;</span><br><span class="line">    <span class="keyword">if</span> (count &lt; obj[i]) &#123;</span><br><span class="line">      count = obj[i]</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">let</span> maxStr = []</span><br><span class="line">  <span class="keyword">for</span>(<span class="keyword">let</span> i <span class="keyword">in</span> obj) &#123;</span><br><span class="line">    <span class="keyword">if</span> (count == obj[i]) &#123;</span><br><span class="line">      maxStr.push(i)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">`出现次数最多的字符：<span class="subst">$&#123;maxStr&#125;</span>，出现次数：<span class="subst">$&#123;count&#125;</span>`</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="数组去重的方法"><a href="#数组去重的方法" class="headerlink" title="数组去重的方法"></a>数组去重的方法</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// es6 的 Set 对象</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">1</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">2</span>,<span class="number">5</span>]</span><br><span class="line"><span class="keyword">var</span> newArr = <span class="keyword">new</span> <span class="built_in">Set</span>(arr)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">Array</span>.from(newArr))</span><br><span class="line"></span><br><span class="line"><span class="comment">// includes，有则true，否则为false</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">1</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">2</span>,<span class="number">5</span>]</span><br><span class="line"><span class="keyword">var</span> newArr = []</span><br><span class="line">arr.forEach(<span class="function"><span class="params">item</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">if</span> (!newArr.includes(item)) &#123;</span><br><span class="line">    newArr.push(item)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(newArr)</span><br><span class="line"></span><br><span class="line"><span class="comment">// indexOf</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">1</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">2</span>,<span class="number">5</span>]</span><br><span class="line"><span class="keyword">var</span> newArr = []</span><br><span class="line">arr.forEach(<span class="function"><span class="params">item</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">if</span> (newArr.indexOf(item) === -<span class="number">1</span>) &#123;</span><br><span class="line">    newArr.push(item)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(newArr)</span><br><span class="line"></span><br><span class="line"><span class="comment">// filter</span></span><br><span class="line"><span class="keyword">var</span> a = [<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">3</span>]</span><br><span class="line"><span class="keyword">var</span> b = a.filter(<span class="function">(<span class="params">item, index</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> a.indexOf(item) === index <span class="comment">// indexOf() 只查找第一个元素，然后返回对应的索引；判断索引是否相同，相同则返回item（因为 filter() 必须为 true 的时候才会返回当前 item，所以需要添加 === index</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(b) <span class="comment">// [1,2,3]</span></span><br></pre></td></tr></table></figure>


<h3 id="js递归求1-100的和"><a href="#js递归求1-100的和" class="headerlink" title="js递归求1-100的和"></a>js递归求1-100的和</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params">num</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (num === <span class="number">1</span>) <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">  <span class="keyword">return</span> num + fn(num -<span class="number">1</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log(fn(<span class="number">100</span>))</span><br></pre></td></tr></table></figure>
      
    </div>
    <div class="article-footer">
      <!-- <blockquote class="mt-2x"> -->
  <!-- <ul class="post-copyright list-unstyled">
    
    <li class="post-copyright-link hidden-xs">
      <strong>本文链接：</strong>
      <a href="https://gitee.com/Yu-Luoboke/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/" title="面试题" target="_blank" rel="external">https://gitee.com/Yu-Luoboke/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/</a>
    </li>
    
    <li class="post-copyright-license">
      <strong>版权声明： </strong> 本博客所有文章除特别声明外，均采用 <a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN协议</a> 许可协议。转载请注明出处！
    </li>
  </ul> -->
<!-- </blockquote> -->


<!-- <div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="http://yu-luoboke.gitee.io/blog" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="/blog/images/avatar.jpg" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="http://yu-luoboke.gitee.io/blog" target="_blank"><span class="text-dark">雨落</span><small class="ml-1x">前端开发-奋斗青年</small></a></h3>
        <div>前端经验总结。</div>
      </div>
    </figure>
  </div>
</div> -->


    </div>
  </article>
  
    

  
</div>

  <nav class="bar bar-footer clearfix" data-stick-bottom>
  <div class="bar-inner">
  
  <ul class="pager pull-left">
    
    <li class="prev">
      <a href="/blog/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/" title="js面试题"><i class="icon icon-angle-left" aria-hidden="true"></i><span>&nbsp;&nbsp;上一篇</span></a>
    </li>
    
    
    <li class="next">
      <a href="/blog/2023/11/09/%E7%9B%91%E5%90%AC%E5%85%83%E7%B4%A0%E5%B0%BA%E5%AF%B8%E5%8F%98%E5%8C%96/" title="js 监听元素尺寸变化"><span>下一篇&nbsp;&nbsp;</span><i class="icon icon-angle-right" aria-hidden="true"></i></a>
    </li>
    
    
  </ul>
  
  
  
  <div class="bar-right">
    
  </div>
  </div>
</nav>
  


</main>

  <footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
	
	
    <ul class="social-links">
    	
        <li><a href="http://yu-luoboke.gitee.io/blog" target="_blank" title="Github" ><i class="icon icon-github"></i></a></li>
        
    </ul>

    <div class="copyright">
    	
        &copy; 2024 lianghongming
        
        <div class="publishby">
        	Theme by <a href="https://gitee.com/Yu-Luoboke/blog" target="_blank"> blog </a>base on <a href="https://gitee.com/Yu-Luoboke/blog" target="_blank">pure</a>.
        </div>
    </div>
</footer>
  <script src="//cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>

<script src="/blog/js/plugin.min.js"></script>


<script src="/blog/js/application.js"></script>


    <script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: '文章',
            PAGES: '页面',
            CATEGORIES: '分类',
            TAGS: '标签',
            UNTITLED: '(未命名)',
        },
        ROOT_URL: '/blog/',
        CONTENT_URL: '/blog/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>

<script src="/blog/js/insight.js"></script>






   









</body>
</html>